﻿using System;
using System.Threading;
using NthDownload.Contracts.Plugins.BandwidthProviders;
using System.Xml.Linq;

namespace NthDownload.BandwidthProviderPlugins
{
    public class SpeedLimitBandwidthProviderXmlSerializationService : IBandwidthProviderXmlSerializationService
    {
        private readonly string _pluginGUID;
        private readonly SynchronizationContext _uiSynchronizationContext;

        public SpeedLimitBandwidthProviderXmlSerializationService(string pluginGUID, SynchronizationContext uiSynchronizationContext)
        {
            _pluginGUID = pluginGUID;
            _uiSynchronizationContext = uiSynchronizationContext;
        }

        public XElement Serialize(IBandwidthProvider bandwidthProvider)
        {
            SpeedLimitBandwidthProvider speedLimitBandwidthProvider = bandwidthProvider as SpeedLimitBandwidthProvider;

            if (speedLimitBandwidthProvider == null)
            {
                throw new Exception("Unexpected type, recieved '" + bandwidthProvider.GetType() + "' expected '" + typeof(SpeedLimitBandwidthProvider) + "'.");
            }

            //
            // Build XML
            //
            XElement rootElement = new XElement("Data");

            rootElement.SetAttributeValue("GUID", speedLimitBandwidthProvider.GUID);
            rootElement.SetAttributeValue("Name", speedLimitBandwidthProvider.Name);
            rootElement.SetAttributeValue("BytesPerSecond", speedLimitBandwidthProvider.BytesPerSecond);

            return rootElement;
        }

        public IBandwidthProvider Deserialize(XElement data)
        {
            SpeedLimitBandwidthProvider speedLimitBandwidthProvider = null;
            _uiSynchronizationContext.Send(state => speedLimitBandwidthProvider = new SpeedLimitBandwidthProvider(), null);

            if (speedLimitBandwidthProvider == null)
            {
                throw new Exception("Speed limit bandwidth provider initialization failed.");
            }

            //speedLimitBandwidthProvider = new SpeedLimitBandwidthProvider();
            Deserialize(data, speedLimitBandwidthProvider);

            return speedLimitBandwidthProvider;
        }

        public void Deserialize(XElement data, IBandwidthProvider obj)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            SpeedLimitBandwidthProvider speedLimitBandwidthProvider = obj as SpeedLimitBandwidthProvider;

            if (speedLimitBandwidthProvider == null)
            {
                throw new Exception("'" + typeof(SpeedLimitBandwidthProvider) + "' expected '" + obj.GetType() + "' recieved when attempting to deserialize bandwidth provider.");
            }

            speedLimitBandwidthProvider.GUID = (string)data.Attribute("GUID") ?? "";
            speedLimitBandwidthProvider.Name = (string)data.Attribute("Name") ?? "";
            speedLimitBandwidthProvider.BytesPerSecond = (long?)data.Attribute("BytesPerSecond") ?? 200 * 1024;

            speedLimitBandwidthProvider.ParentGUID = _pluginGUID;
        }
    }
}
